package android.slc.box.core.ui;

import android.slc.box.core.notification.NotificationObserver;
import javafx.application.Platform;
import javafx.stage.WindowEvent;

/**
 * @author slc
 * @date 2022/09/26 下午 6:47
 */
public class ViewLifeViewLifeHandleImpl implements ViewLifeHandle, NotificationObserver {
    private boolean bindViewRunLast;
    private ViewLife viewLife;
    private BaseViewModel vm;

    @Override
    public void initViewLife(BaseViewModel vm, boolean bindViewRunLast) {
        initViewLife(vm, null, bindViewRunLast);
    }

    @Override
    public void initViewLife(BaseViewModel vm, ViewLife viewLife, boolean bindViewRunLast) {
        this.bindViewRunLast = bindViewRunLast;
        this.vm = vm;
        this.viewLife = viewLife;
        onCreate();
        subscribeVm();
    }

    @Override
    public void onCreate() {
        if (this.viewLife != null) {
            this.viewLife.onCreate();
        }
    }

    protected void subscribeVm() {
        this.vm.subscribe(BaseViewModel.EVENT_ON_VIEW_ADDED, this);
        this.vm.subscribe(BaseViewModel.EVENT_ON_VIEW_REMOVED, this);
        this.vm.subscribe(BaseViewModel.EVENT_ON_VIEW_DESTROY, this);
        this.vm.subscribe(BaseViewModel.EVENT_FINISH_WINDOW, this);
        this.vm.subscribe(BaseViewModel.EVENT_FINISH_VIEW, this);
    }

    @Override
    public void onViewAdded() {
        if (this.viewLife != null) {
            this.viewLife.onViewAdded();
        }
        onBindViewBefore();
        onBindView();
        onRegisterLiveEvent();
        if (bindViewLaterRunLast()) {
            Platform.runLater(this::executeBindFunc);
            return;
        }
        executeBindFunc();
    }

    private void executeBindFunc() {
        onBindViewLater();
    }

    @Override
    public boolean bindViewLaterRunLast() {
        return this.bindViewRunLast;
    }

    @Override
    public void onBindViewBefore() {
        if (this.viewLife != null) {
            this.viewLife.onBindViewBefore();
        }
    }

    @Override
    public void onBindView() {
        if (this.viewLife != null) {
            this.viewLife.onBindView();
        }
    }

    @Override
    public void onBindViewLater() {
        if (this.viewLife != null) {
            this.viewLife.onBindViewLater();
        }
    }

    @Override
    public void onRegisterLiveEvent() {
        if (this.viewLife != null) {
            this.viewLife.onRegisterLiveEvent();
        }
    }

    @Override
    public void onViewRemoved() {
        if (this.viewLife != null) {
            this.viewLife.onViewRemoved();
        }
    }

    @Override
    public void onDestroy() {
        if (this.viewLife != null) {
            this.viewLife.onDestroy();
            this.viewLife = null;
        }
        this.vm.unsubscribe(BaseViewModel.EVENT_ON_VIEW_ADDED, this);
        this.vm.unsubscribe(BaseViewModel.EVENT_ON_VIEW_REMOVED, this);
        this.vm.unsubscribe(BaseViewModel.EVENT_ON_VIEW_DESTROY, this);
        this.vm.unsubscribe(BaseViewModel.EVENT_FINISH_WINDOW, this);
        this.vm.unsubscribe(BaseViewModel.EVENT_FINISH_VIEW, this);
        this.vm = null;
    }

    @Override
    public void finish() {
        if (this.viewLife != null) {
            this.viewLife.finish();
        }
    }

    @Override
    public void finishView() {
        if (this.viewLife != null) {
            this.viewLife.finishView();
        }
    }

    /*@Override
    public final boolean handle(WindowEvent event) {
        if (WindowEvent.WINDOW_CLOSE_REQUEST.equals(event.getEventType())) {
            if (this.vm != null) {
                //onDestroy();
                this.vm.onViewRemoved(false);
            }
        }
    }*/

    @Override
    public void receivedNotification(String key, Object... payload) {
        switch (key) {
            case BaseViewModel.EVENT_ON_VIEW_ADDED:
                onViewAdded();
                break;
            case BaseViewModel.EVENT_ON_VIEW_REMOVED:
                onViewRemoved();
                break;
            case BaseViewModel.EVENT_ON_VIEW_DESTROY:
                onDestroy();
                break;
            case BaseViewModel.EVENT_FINISH_WINDOW:
                finish();
                break;
            case BaseViewModel.EVENT_FINISH_VIEW:
                finishView();
                break;
        }
    }
}
